package com.lfp.consumer.callback;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @Description TODO
 * @Author lfp
 * @Date 2022/7/19
 * @Version 1.0
 */
@Slf4j
@Component
public class ConfirmExchangeCallBack implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback {
    //注入RabbitTemplate
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct //该方法在ConfirmExchangeCallBack实例化、RabbitTemplate注入之后执行
    public void init(){
        rabbitTemplate.setConfirmCallback(this);//给RabbitTemplate 设置回调接口
        rabbitTemplate.setReturnCallback(this);//给RabbitTemplate 设置回退接口
    }

    /**
    * 交换机确认回调方法，成功或失败都会调用
    *    1、发消息  交换机收到了  回调
     *    1.1 correlationData 保存回调消息的ID及相关信息
     *    1.2 ack=true 应答
     *    1.3 cause null
     *
     *    2、发消息  交换机接收失败了  回调
     *      2.1 correlationData 保存回调消息的ID及相关信息
     *      2.2 ack=false 应答
     *      2.3 cause 失败的原因
    *
    */

    //CorrelationData 是消息发送方，发送消息时传递的，如果不传，就接收不到
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        String id = correlationData != null?correlationData.getId():"";

        if(ack){
            log.info("交换机已经收到Id为：{}的消息",id);
        }else {
            log.error("交换机还未收到id为：{}的消息，原因是：{}",id,cause);
        }
    }

    //实现消息回退接口  当在消息传递过程中不可达到目的地时，将消息返回给生产者
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        log.error("消息：{}，被交换机：{}退回，退回原因：{},路由Key:{}",
                new String(message.getBody()),exchange,replyText,routingKey);
    }
}
